package com.sunnybear.framework.tools;

import android.app.Activity;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * Activity管理工具类,将activity放入栈统一管理
 *  2018/3/17.
 */
public class ActivityStackManager {
    private static volatile ActivityStackManager mInstance;
    private static Stack<Activity> mActivityStack;

    public static ActivityStackManager getInstance() {
        if (null == mInstance)
            synchronized (ActivityStackManager.class) {
                if (null == mInstance)
                    mInstance = new ActivityStackManager();
            }
        return mInstance;
    }

    private ActivityStackManager() {
        mActivityStack = new Stack<>();
    }

    /**
     * 打印栈信息
     *
     * @return 栈信息
     */
    public String printStack() {
        StringBuilder buffer = new StringBuilder("[");
        for (Activity activity : mActivityStack) {
            buffer.append(activity.getClass().getSimpleName()).append(",");
        }
        return buffer.delete(buffer.length() - 1, buffer.length()).append("]").toString();
    }


    public boolean isAtTop(Activity activity) {
        return mActivityStack.get(mActivityStack.size() - 1).equals(activity);
    }

    public boolean isAtTop(Class activity) {
        return (mActivityStack.get(mActivityStack.size() - 1).getClass().isAssignableFrom(activity));
    }

    /**
     * 入栈
     *
     * @param activity Activity
     */
    public void addActivity(Activity activity) {
        mActivityStack.push(activity);
    }

    /**
     * 出栈
     *
     * @param activity Activity
     */
    public void removeActivity(Activity activity) {
        mActivityStack.remove(activity);
    }

    /**
     * 彻底退出
     */
    public void finishAllActivity() {
        Activity activity;
        while (!mActivityStack.empty()) {
            activity = mActivityStack.pop();
            if (activity != null)
                activity.finish();
        }
    }

    /**
     * 结束指定类名的Activity
     *
     * @param cls Class
     */
    public void finishActivity(Class<?> cls) {
        for (Activity activity : mActivityStack) {
            if (activity.getClass().equals(cls)) {
                finishActivity(activity);
                break;
            }
        }
    }

    /**
     * 查找栈中是否存在指定的activity
     *
     * @param cls Class
     * @return 是否存在
     */
    public boolean checkActivity(Class<? extends Activity> cls) {
        for (Activity activity : mActivityStack) {
            if (activity.getClass().equals(cls))
                return true;
        }
        return false;
    }

    /**
     * 查找栈中是否存在指定的activity
     *
     * @param check Activity
     * @return 是否存在
     */
    public boolean checkActivity(Activity check) {
        for (Activity activity : mActivityStack) {
            if (activity.equals(check))
                return true;
        }
        return false;
    }

    /**
     * 结束指定的Activity
     *
     * @param activity Activity
     */
    public static void finishActivity(Activity activity) {
        if (activity != null) {
            mActivityStack.remove(activity);
            activity.finish();
        }
    }

    /**
     * finish指定的activity之上所有的activity
     *
     * @param actCls        指定目标
     * @param isIncludeSelf 是否包含自己
     * @return 栈中是否存在该目标、不存在则失败
     */
    public boolean finishToActivity(Class<? extends Activity> actCls, boolean isIncludeSelf) {
        return checkActivity(actCls) && finishToActivity(actCls, false, isIncludeSelf);
    }

    /**
     * finish指定的activity之上所有的activity
     *
     * @param actCls          指定目标
     * @param isIncludeTarget 是否包含目标
     * @param isIncludeSelf   是否包含自己
     * @return 栈中是否存在该目标、不存在则失败
     */
    public boolean finishToActivity(Class<? extends Activity> actCls, boolean isIncludeTarget, boolean isIncludeSelf) {
        if (!checkActivity(actCls)) {
            return false;
        }
        List<Activity> buf = new ArrayList<>();
        int size = mActivityStack.size();
        Activity activity;
        for (int i = size - 1; i >= 0; i--) {
            activity = mActivityStack.get(i);
            if (activity.getClass().isAssignableFrom(actCls)) {
                if (isIncludeTarget) {
                    buf.add(activity);
                }
                for (Activity a : buf) {
                    finishActivity(a);
                }
                return true;
            } else if (i == size - 1 && isIncludeSelf) {
                buf.add(activity);
            } else if (i != size - 1) {
                buf.add(activity);
            }
        }
        return false;
    }

    /**
     * finish指定的activity之外所有的activity
     *
     * @param actCls Class
     * @return result
     */
    public static boolean finishOtherActivity(Class<? extends Activity> actCls) {
        List<Activity> buf = new ArrayList<>();
        int size = mActivityStack.size();
        boolean flag = false;
        for (int i = size - 1; i >= 0; i--) {
            Activity activity = mActivityStack.get(i);
            if (activity.getClass().isAssignableFrom(actCls)) {
                flag = true;
            } else {
                buf.add(activity);
            }
        }
        for (Activity a : buf) {
            finishActivity(a);
        }
        return flag;
    }

    /**
     * @return 获取当前栈顶的activity
     */
    public Activity top() {
        if (!mActivityStack.isEmpty()) {
            return mActivityStack.get(mActivityStack.size() - 1);
        } else {
            return null;
        }
    }

    /**
     * 查找栈中是否存在指定的activity
     *
     * @param cls String
     * @return Activity
     */
    public Activity getActivity(String cls) {
        for (Activity activity : mActivityStack) {
            if (activity.getClass().getSimpleName().equals(cls)) {
                return activity;
            }
        }
        return null;
    }

    /**
     * 仅保留栈顶的activity
     */

    public void finishMostActivity(){
        for (int i=0;i<mActivityStack.size();i++){
            if(i!=mActivityStack.size()-1){
                finishActivity(mActivityStack.get(i));
            }
        }
    }
}
